home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / CALib & You… / Source / CASample / CAS_Dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-07  |  22.8 KB  |  882 lines  |  [TEXT/MPS ]

  1. /*
  2.  
  3.     File:        CAS_Dialog.c
  4.  
  5.     Contains:    Utility routines for dialogs & controls.
  6.  
  7.     Written by:    David H Nelson
  8.  
  9.     Copyright © 1988-1995 ComponentWorks, All rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.                  01/17/95    DAS        changed all FrontWindow() calls to
  14.                                      App_GetFrontDocWindow() to account for
  15.                                      floating windows.
  16.                  1/14/95    DAS        conversion of some DialogMgr API calls into their new names
  17.                   1/15/95    DHN        Fixed bDialogFilter results so it doesn't handle keystrokes
  18.                                      that it shouldn't. Changed many variable names for clarity.
  19.                 ----------------------------
  20.                  ?/?/88        DHN        Created.
  21. */
  22.  
  23. #ifdef USE_CALIB
  24. #include "CALib.h"
  25. #endif
  26.  
  27. #include "CAS_Globals.h"
  28.  
  29. #include "CAS_Dialog.h"
  30. #include "CAS_App.h"
  31. #include "CAS_StringTools.h"
  32.  
  33.  
  34.  
  35. //----------------------------------------------------------------------------
  36. void Dialog_CenterALRT(
  37.     short    ID )
  38. {
  39. Rect        rScreen;
  40. AlertTHndl    theALRT;
  41.  
  42.     theALRT = (AlertTHndl)GetResource( 'ALRT', ID );
  43.     if (theALRT == nil)
  44.         return;
  45.  
  46.     GetMainScreenRect( &rScreen );
  47.     rScreen.top += GetMBarHeight() + 4;
  48.  
  49.     rCenterRectInRect( &rScreen, &((**theALRT).boundsRect) );
  50.  
  51.     ChangedResource( (Handle)theALRT );
  52.     ReleaseResource( (Handle)theALRT );
  53. }
  54.  
  55. //----------------------------------------------------------------------------
  56. void Dialog_CenterALRTonFrontWindow(
  57.     short    ID )
  58. {
  59. Rect             rFrontWindow;
  60. AlertTHndl        theALRT;
  61. WindowPtr        theWindow;
  62.  
  63.     theALRT = (AlertTHndl)GetResource( 'ALRT', ID );
  64.     if (theALRT == nil)
  65.         return;
  66.  
  67.     // DAS: changed from FrontWindow() to App_GetFrontDocWindow to handle
  68.     // floating windows.
  69.     theWindow = App_GetFrontDocWindow();
  70.     if (theWindow == nil)
  71.         GetMainScreenRect( &rFrontWindow );
  72.     else
  73.         rFrontWindow = theWindow->portRect;
  74.     RectLocalToGlobal( &rFrontWindow );
  75.     rCenterRectInRect( &rFrontWindow, &((**theALRT).boundsRect) );
  76.     
  77.     // If the top-left or bot-right corners of the dialog are off screen, center 
  78.     // the dialog on the main screen. (Note: It is not possible to correctly move 
  79.     // the window onto the desktop region nearest the center point without parsing 
  80.     // the rgn.)
  81.     if (!PtInRgn( topLeft((**theALRT).boundsRect), LMGetGrayRgn() ) ||
  82.         !PtInRgn( botRight((**theALRT).boundsRect), LMGetGrayRgn() ))
  83.     {
  84.         GetMainScreenRect( &rFrontWindow );
  85.         rCenterRectInRect( &rFrontWindow, &((**theALRT).boundsRect) );
  86.     }
  87.     
  88.     ChangedResource( (Handle)theALRT );
  89.     ReleaseResource( (Handle)theALRT );
  90. }
  91.  
  92. //----------------------------------------------------------------------------
  93. // Center the given DLOG on the front most window.
  94. // This must be called before GetNewDialog.
  95.  
  96. void Dialog_CenterDLOG(
  97.     short    ID )
  98. {
  99. Rect            rScreen;
  100. DialogTHndl        theDLOG;
  101.  
  102.     theDLOG = (DialogTHndl)GetResource( 'DLOG', ID );
  103.     if (theDLOG == nil)
  104.         return;
  105.  
  106.     GetMainScreenRect( &rScreen );
  107.     rScreen.top += GetMBarHeight() + 4;
  108.     
  109.     rCenterRectInRect( &rScreen, &((**theDLOG).boundsRect) );
  110.     
  111.     ChangedResource( (Handle)theDLOG );
  112.     ReleaseResource( (Handle)theDLOG );
  113. }
  114.  
  115. //----------------------------------------------------------------------------
  116. // Center the given DLOG on the front most window. This must be called before
  117. // GetNewDialog.
  118.  
  119. void Dialog_CenterDLOGonFrontWindow(
  120.     short    ID )
  121. {
  122. Rect             rFrontWindow;
  123. DialogTHndl        theDLOG;
  124. WindowPtr        theWindow;
  125.  
  126.     theDLOG = (DialogTHndl)GetResource( 'DLOG', ID );
  127.     if (theDLOG == nil)
  128.         return;
  129.  
  130.     // DAS: changed from FrontWindow() to App_GetFrontDocWindow to handle
  131.     // floating windows.
  132.     theWindow = App_GetFrontDocWindow();
  133.     if (theWindow == nil)
  134.         GetMainScreenRect( &rFrontWindow );
  135.     else
  136.         rFrontWindow = theWindow->portRect;
  137.     RectLocalToGlobal( &rFrontWindow );
  138.     if (theWindow == nil)
  139.         GetMainScreenRect( &rFrontWindow );
  140.  
  141.     rCenterRectInRect( &rFrontWindow, &((**theDLOG).boundsRect) );
  142.     
  143.     // If the top-left or bot-right corners of the dialog are off screen, center 
  144.     // the dialog on the main screen. (Note: It is not possible to correctly move 
  145.     // the window onto the desktop region nearest the center point without parsing 
  146.     // the rgn.)
  147.     if (!PtInRgn( topLeft((**theDLOG).boundsRect), LMGetGrayRgn() ) ||
  148.         !PtInRgn( botRight((**theDLOG).boundsRect), LMGetGrayRgn() ))
  149.     {
  150.         GetMainScreenRect( &rFrontWindow);
  151.         rCenterRectInRect( &rFrontWindow, &((**theDLOG).boundsRect) );
  152.     }
  153.     
  154.     ChangedResource( (Handle)theDLOG );
  155.     ReleaseResource( (Handle)theDLOG );
  156. }
  157.  
  158.  
  159. //----------------------------------------------------------------------------
  160.  
  161. Point Dialog_TopLeftCenteredDLOG(
  162.     short    iDLOG )
  163. {
  164. Handle    hDialog;
  165. Rect    rDialog, rScreen;
  166. Point    targetPt;
  167.  
  168.     GetMainScreenRect( &rScreen );
  169.     rScreen.top += GetMBarHeight() + 4;
  170.  
  171.     hDialog = GetResource( 'DLOG', iDLOG );
  172.     if (hDialog == nil)
  173.     {
  174.         targetPt.h = 0;
  175.         targetPt.v = 0;
  176.     }
  177.     else
  178.     {
  179.         rDialog = *(Rect*)*hDialog;
  180.         rCenterRectInRect( &rScreen, &rDialog );
  181.  
  182.         targetPt.h = rDialog.left;
  183.         targetPt.v = rDialog.top;
  184.  
  185.         ChangedResource( hDialog );
  186.         ReleaseResource( hDialog );
  187.     }
  188.  
  189.     return targetPt;
  190. }
  191.  
  192. //---------------------------------------------------------------------------
  193. // given a dialog and a range of radio buttons, turn all off except activeItem.
  194.  
  195. void Dialog_SetCheckBox(
  196.     DialogPtr    theDialog,
  197.     short        checkItem,
  198.     Boolean        bCheckValue )
  199. {
  200. ControlHandle    theControl;
  201.     
  202.     theControl = (ControlHandle)Dialog_GetItemHandle( theDialog, checkItem );
  203.     if (theControl != nil)
  204.         SetControlValue( theControl, bCheckValue ? 1 : 0 );
  205. }
  206.  
  207. //---------------------------------------------------------------------------
  208. // given a dialog and a range of radio buttons, turn all off except activeItem.
  209.  
  210. Boolean Dialog_GetCheckBox(
  211.     DialogPtr    theDialog,
  212.     short        checkItem )
  213. {
  214. ControlHandle    theControl;
  215.     
  216.     theControl = (ControlHandle)Dialog_GetItemHandle( theDialog, checkItem );
  217.     if (theControl != nil)
  218.         return (GetControlValue( theControl ) != 0);
  219.  
  220.     return false;
  221. }
  222.  
  223. //---------------------------------------------------------------------------
  224. // given a dialog and a range of radio buttons, turn all off except activeItem.
  225.  
  226. void Dialog_ToggleCheckBox(
  227.     DialogPtr    theDialog,
  228.     short        checkItem )
  229. {
  230. ControlHandle    theControl;
  231.     
  232.     theControl = (ControlHandle)Dialog_GetItemHandle( theDialog, checkItem );
  233.     if (theControl != nil)
  234.         SetControlValue( theControl, GetControlValue( theControl ) ? 0 : 255 );
  235. }
  236.  
  237. //---------------------------------------------------------------------------
  238. // given a dialog and a range of radio buttons, turn all off except activeItem.
  239.  
  240. void Dialog_SetRadioGroup(
  241.     DialogPtr    theDialog,
  242.     short        startItem,
  243.     short        endItem,
  244.     short        activeItem )
  245. {
  246. ControlHandle    theControl;
  247. short            i;
  248.     
  249.     for (i = startItem; i <= endItem; i++)
  250.     {
  251.         theControl = (ControlHandle)Dialog_GetItemHandle( theDialog, i );
  252.         if (theControl != nil)
  253.             SetControlValue( theControl, (i == activeItem) ? 1 : 0 );
  254.     }
  255. }
  256.  
  257. //---------------------------------------------------------------------------
  258. // given a dialog box and a range of radio buttons, return the active button's number
  259. // return zero if none were on.
  260.  
  261. short Dialog_GetRadioGroup(
  262.     DialogPtr    theDialog,
  263.     short        startItem,
  264.     short        endItem )
  265. {
  266. ControlHandle    theControl;
  267. short            i;
  268.  
  269.     for (i = startItem; i <= endItem; i++)
  270.     {
  271.         theControl = (ControlHandle)Dialog_GetItemHandle( theDialog, i );
  272.         if (theControl != nil)
  273.             if (GetControlValue( theControl ) != 0)
  274.                 break;
  275.     }
  276.  
  277.     if (i > endItem)
  278.         i = 0;
  279.  
  280.     return i;
  281. }
  282.  
  283. //---------------------------------------------------------------------------
  284. // Return the menu handle from a pop up CDEF control. Since we can't call 
  285. // GetMHandle to access the menu handle, we have to look at the data stored 
  286. // in the control record.
  287.  
  288. MenuHandle GetPopUpMenuHandle(
  289.     ControlHandle    thisControl )
  290. {
  291.     if (thisControl == nil)
  292.         return nil;
  293.  
  294.     return (**((popupPrivateDataHdl)(*thisControl)->contrlData)).mHandle;
  295. }
  296.  
  297. //---------------------------------------------------------------------------
  298. // Set the menu handle of a pop up CDEF control.
  299. // We have to stuff the data in the control record
  300.  
  301. void SetPopUpMenuHandle(
  302.     ControlHandle    thisControl,
  303.     MenuHandle        theMenu )
  304. {
  305.     if ((thisControl != nil) && (theMenu != nil))
  306.         (**((popupPrivateDataHdl)(*thisControl)->contrlData)).mHandle = theMenu;
  307. }
  308.  
  309. //---------------------------------------------------------------------------
  310. // Given a string and a menu, return the item number of the last menu item 
  311. // that matches the string.
  312.  
  313. short ItemStringToItem(
  314.     Str255        theItemString,
  315.     MenuHandle    theMenu )
  316. {
  317. Str255        theString;
  318. short        index;
  319.  
  320.     index = CountMItems( theMenu );
  321.     while (index > 0)
  322.     {
  323.         GetMenuItemText( theMenu, index, theString );
  324.         if (EqualString( theString, theItemString, false, false ))
  325.             break;
  326.  
  327.         index--;
  328.     }
  329.  
  330.     return index;
  331. }
  332.  
  333.  
  334. //---------------------------------------------------------------------------
  335. // Given a font number and a menu, return the last menu item that matches the
  336. // font's name.
  337. short FontToMenuItem(
  338.     short        fontFamilyNumber,
  339.     MenuHandle    theMenu )
  340. {
  341. Str255    fontName;
  342.  
  343.     GetFontName( fontFamilyNumber, fontName );
  344.     return ItemStringToItem( fontName, theMenu );
  345. }
  346.  
  347.  
  348. //---------------------------------------------------------------------------
  349. // Given a font size and a menu, return the last menu item that matches the
  350. // size.
  351. short SizeToMenuItem(
  352.     short        theSize,
  353.     MenuHandle    theMenu )
  354. {
  355. Str255        theString;
  356.  
  357. //    if (theSize == 9)
  358. //        return(1);
  359.     NumToString( (long)theSize, theString );
  360.     return ItemStringToItem( theString, theMenu );    
  361. }
  362.  
  363. //----------------------------------------------------------------------------
  364. // Dialog_GetItemHandle
  365. Handle Dialog_GetItemHandle(
  366.     DialogPtr    theDialog,
  367.     short        itemNum )
  368. {
  369. Rect    itemRect;
  370. Handle    itemHandle;
  371. short    itemKind;
  372.  
  373.     itemHandle = nil;
  374.     if ((theDialog != nil) && (itemNum > 0))
  375.         GetDialogItem( theDialog, itemNum, &itemKind, &itemHandle, &itemRect );
  376.  
  377.     return itemHandle;
  378. }
  379.  
  380. //----------------------------------------------------------------------------
  381. void Dialog_SetItemHandle(
  382.     DialogPtr    theDialog,
  383.     short        itemNum,
  384.     Handle        theHandle )
  385. {
  386. Rect    itemRect;
  387. Handle    itemHandle;
  388. short    itemKind;
  389.  
  390.     GetDialogItem( theDialog, itemNum, &itemKind, &itemHandle, &itemRect );
  391.     SetDialogItem( theDialog, itemNum, itemKind, theHandle, &itemRect );
  392. }
  393.  
  394. //----------------------------------------------------------------------------
  395. void Dialog_GetItemRect(
  396.     DialogPtr    theDialog,
  397.     short        theID,
  398.     Rect        *theRect )
  399. {
  400. Handle    itemHandle;
  401. short    itemKind;
  402.  
  403.     GetDialogItem( theDialog, theID, &itemKind, &itemHandle, theRect );
  404. }
  405.  
  406. //----------------------------------------------------------------------------
  407. void Dialog_SetItemRect(
  408.     DialogPtr    theDialog,
  409.     short        theID,
  410.     Rect        *theRect )
  411. {
  412. Rect    itemRect;
  413. Handle    itemHandle;
  414. short    itemKind;
  415.  
  416.     GetDialogItem( theDialog, theID, &itemKind, &itemHandle, &itemRect );
  417.     SetDialogItem( theDialog, theID, itemKind, itemHandle, theRect );
  418. }
  419.  
  420. //----------------------------------------------------------------------------
  421. short Dialog_GetItemKind(
  422.     DialogPtr    theDialog,
  423.     short        theID )
  424. {
  425. Rect    itemRect;
  426. Handle    itemHandle;
  427. short    itemKind;
  428.  
  429.     GetDialogItem( theDialog, theID, &itemKind, &itemHandle, &itemRect );
  430.     return itemKind;
  431. }
  432.  
  433. //----------------------------------------------------------------------------
  434. void Dialog_InvalItemRect(
  435.     DialogPtr    theDialog,
  436.     short        itemNum )
  437. {
  438. Rect        theRect;
  439. GrafPtr        savePort;
  440.  
  441.     // make sure the item number is valid.
  442. //    if (itemNum < 1 || itemNum > CountDITL(theDialog))
  443. //        return;
  444.         
  445.     GetPort( &savePort );
  446.     SetPort( theDialog );
  447.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  448.     InvalRect( &theRect );
  449.     SetPort( savePort );
  450. }
  451.  
  452. //----------------------------------------------------------------------------
  453. void Dialog_OutlineButton(
  454.     DialogPtr    theDialog,
  455.     short        itemNum )
  456. {
  457. Rect        theRect;
  458. PenState    pnState;
  459.  
  460.     // make sure the item number is valid.
  461. //    if (itemNum < 1 || itemNum > CountDITL(theDialog))
  462. //        return;
  463.         
  464.     GetPenState( &pnState );
  465.     PenNormal();
  466.     PenSize( 3, 3 );
  467.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  468.     InsetRect( &theRect,-4, -4 );
  469.     FrameRoundRect( &theRect, 16, 16 );
  470.     SetPenState( &pnState );
  471. }
  472.  
  473. //----------------------------------------------------------------------------
  474. void Dialog_FrameItem(
  475.     DialogPtr    theDialog,
  476.     short        itemNum )
  477. {
  478. Rect        theRect;
  479. PenState    pnState;
  480.  
  481.     // make sure the item number is valid.
  482. //    if (itemNum < 1 || itemNum > CountDITL(theDialog))
  483. //        return;
  484.         
  485.     GetPenState( &pnState );
  486.     PenNormal();
  487.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  488.     FrameRect( &theRect );
  489.     SetPenState( &pnState );
  490. }
  491.  
  492. //----------------------------------------------------------------------------
  493. void Dialog_GrayLine(
  494.     DialogPtr    theDialog,
  495.     short        itemNum )
  496. {
  497. Rect        theRect;
  498. PenState    pnState;
  499.  
  500.     GetPenState( &pnState );
  501.     PenNormal();
  502.     PenPat( (ConstPatternParam)&qd.gray );    // ConstPatternParam from non-universal THINK C headers
  503.  
  504.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  505.     MoveTo( theRect.left, theRect.top );
  506.     if (theRect.right - theRect.left > theRect.bottom - theRect.top)
  507.         LineTo( theRect.right, theRect.top );
  508.     else
  509.         LineTo( theRect.left, theRect.bottom );
  510.  
  511.     SetPenState( &pnState );
  512. }
  513.  
  514.  
  515. //----------------------------------------------------------------------------
  516. void Dialog_SizeTextItem(
  517.     DialogPtr    theDialog,
  518.     short        itemNum )
  519. {
  520. short    iFont, iSize;
  521. Rect    theRect;
  522. Str255    s0;
  523.  
  524.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  525.     GetDialogItemText( Dialog_GetItemHandle( theDialog, itemNum ), s0 );
  526.     iFont = theDialog->txFont;
  527.     iSize = theDialog->txSize;
  528.     TextFont( systemFont );
  529.     TextSize( 0 );
  530.     theRect.right = theRect.left + TextWidth( s0+1, 0, s0[0] ) + 1;
  531.     TextFont( iFont );
  532.     TextSize( iSize );
  533.     Dialog_SetItemRect( theDialog, itemNum, &theRect );
  534. }
  535.  
  536.  
  537. //----------------------------------------------------------------------------
  538. void Dialog_SetTextItem(
  539.     DialogPtr    theDialog,
  540.     short        itemNum,
  541.     Str255        theString )
  542. {
  543. short        iFont, iSize;
  544. Rect        theRect;
  545. GrafPtr        savePort;
  546.  
  547.     GetPort( &savePort );
  548.     SetPort( theDialog );
  549.  
  550.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  551.     EraseRect( &theRect );
  552.     InvalRect( &theRect );
  553.  
  554.     iFont = theDialog->txFont;
  555.     iSize = theDialog->txSize;
  556.     TextFont( systemFont );
  557.     TextSize( 0 );
  558.     theRect.right = theRect.left + TextWidth( theString+1, 0, theString[0] ) + 1;
  559.     TextFont( iFont );
  560.     TextSize( iSize );
  561.     SetDialogItemText( Dialog_GetItemHandle( theDialog, itemNum ), theString );
  562.  
  563.     SetPort( savePort );
  564. }
  565.  
  566.  
  567. //----------------------------------------------------------------------------
  568. void Dialog_SetUserProc(
  569.     DialogPtr    theDialog,
  570.     short        itemNum,
  571.     pascal void    (*proc)( WindowPtr theWindow, short itemNum ) )
  572. {
  573. Rect    theRect;
  574. Handle    theHandle;
  575. short    itemKind;
  576.  
  577.     GetDialogItem( theDialog, itemNum, &itemKind, &theHandle, &theRect );
  578.     SetDialogItem( theDialog, itemNum, itemKind, (Handle)proc, &theRect );
  579. }
  580.  
  581. //----------------------------------------------------------------------------
  582. void Dialog_RedrawDialogs( void )
  583. {
  584. WindowPeek    theWindow;
  585. GrafPtr        savePort;
  586.  
  587.     GetPort( &savePort );
  588.     theWindow = (WindowPeek)FrontWindow();
  589.     
  590.     while (theWindow != nil)
  591.     {
  592.         if (theWindow->windowKind == dialogKind)
  593.         {
  594.             SetPort( (GrafPtr)theWindow );
  595.             if (((DialogPeek)theWindow)->aDefItem)
  596.                 Dialog_OutlineButton( (WindowPtr)theWindow, ((DialogPeek)theWindow)->aDefItem );    // iOKITEM
  597.             BeginUpdate( (WindowPtr)theWindow );
  598.             UpdateDialog( (WindowPtr)theWindow, ((WindowPtr)theWindow)->visRgn );
  599.             EndUpdate( (WindowPtr)theWindow );
  600.         }
  601.  
  602.         theWindow = theWindow->nextWindow;
  603.     }
  604.  
  605.     SetPort( savePort );
  606. }
  607.  
  608. //----------------------------------------------------------------------------
  609. short Dialog_GetIconID(
  610.     DialogPtr    theDialog,
  611.     short        itemNum )
  612. {
  613. Str255    sName;
  614. Rect    itemRect;
  615. ResType    theType;
  616. Handle    itemHandle;
  617. short    itemKind, theID;
  618.  
  619.     GetDialogItem( theDialog, itemNum, &itemKind, &itemHandle, &itemRect );
  620.     GetResInfo( itemHandle, &theID, &theType, sName );
  621.  
  622.     return theID;
  623. }
  624.  
  625. //----------------------------------------------------------------------------
  626. void Dialog_DrawCenteredStr(
  627.     DialogPtr    theDialog,
  628.     short        itemNum,
  629.     StringPtr    theString )
  630. {
  631. Rect    theRect;
  632. Str255    sDst;
  633.  
  634.     Dialog_GetItemRect( theDialog, itemNum, &theRect );
  635.     sTrimText( theString, sDst, theRect.right-theRect.left );
  636.     sCopyStr( theString, sDst );
  637.     TextBox( sDst+1, (long)sDst[0], &theRect, teJustCenter );
  638. }
  639.  
  640. //----------------------------------------------------------------------------
  641. Boolean Dialog_ControlEnabled(
  642.     ControlHandle    theControl )
  643. {
  644.     return ((**theControl).contrlHilite != (Byte)255);
  645. }
  646.  
  647. //----------------------------------------------------------------------------
  648. void Dialog_BlinkControl(
  649.     ControlHandle    theControl )
  650. {
  651. long    finalTicks;
  652.  
  653.     HiliteControl( theControl, 1 );
  654.     Delay( 8L, &finalTicks );
  655.     HiliteControl( theControl, 0 );
  656. }
  657.  
  658. //----------------------------------------------------------------------------
  659. Boolean bDialogFilter(
  660.     DialogPtr    theDialog,
  661.     EventRecord    *theEvent,
  662.     short        *itemHit,
  663.     Boolean        (*filterProc)( DialogPtr, EventRecord*, short* ) )
  664. {
  665. char            theCharCode;
  666. short            iKind, iItem, iCount, iControlItem;
  667. Str255            s0;
  668. ControlHandle    hControl;
  669. Rect            rRect;
  670. GrafPtr            savePort;
  671.  
  672. static long        lLastTime = (-1L);
  673. static Point    LastPt = { 0, 0 };
  674.  
  675.     if (filterProc != nil)
  676.         if ((*filterProc)( theDialog, theEvent, itemHit ))
  677.             return true;
  678.  
  679.     switch (theEvent->what)
  680.     {
  681.         case nullEvent:
  682.             if (((DialogPeek)theDialog)->editField != -1)
  683.             {
  684.                 GlobalToLocal( &theEvent->where );
  685.                 Dialog_GetItemRect( theDialog, ((DialogPeek)theDialog)->editField+1, &rRect );
  686.                 if (PtInRect( theEvent->where, &rRect ))
  687.                     bSetCursor( iBeamCursor );
  688.                 else
  689.                     bSetCursor( arrowCursor );
  690.             }
  691.             else
  692.                 bSetCursor( arrowCursor );
  693.             break;
  694.             
  695.         case mouseDown:
  696.             // detect double clicks.
  697.             if (((theEvent->when - lLastTime) <= LMGetDoubleTime())
  698.                 && bAlmostEqual( LastPt, theEvent->where, 3 ))
  699.             {
  700.                 LastPt = theEvent->where;
  701.                 GlobalToLocal( &LastPt );
  702.                 iItem = FindDialogItem( theDialog, LastPt ) + 1;
  703.                 if (iItem > 0)
  704.                 {
  705.                     GetDialogItem( theDialog, iItem, &iKind, (Handle*)&hControl, &rRect );
  706.                     if (iKind == (ctrlItem+radCtrl) && Dialog_ControlEnabled( hControl ))
  707.                     {
  708.                         if (iOKITEM && Dialog_ControlEnabled(
  709.                             (ControlHandle)Dialog_GetItemHandle( theDialog, iOKITEM ) ))
  710.                         {
  711.                             lLastTime = -1;
  712.                             LastPt.h = LastPt.v = 0;
  713.                             *itemHit = iOKITEM;
  714.                             return true;
  715.                         }
  716.                     }
  717.                 }
  718.             }
  719.  
  720.             lLastTime = theEvent->when;
  721.             LastPt = theEvent->where;
  722.             break;
  723.             
  724.         case keyDown:
  725.         case autoKey:
  726.             // if it was the return or enter key…
  727.             if (iOKITEM
  728.                 && (((theEvent->message & charCodeMask) == 3)
  729.                     || ((theEvent->message & charCodeMask) == 13)))
  730.             {
  731.                 // if the OK button is enabled, hit it
  732.                 hControl = (ControlHandle)Dialog_GetItemHandle( theDialog, iOKITEM );
  733.                 if (Dialog_ControlEnabled( hControl ))
  734.                 {
  735.                     Dialog_BlinkControl( hControl );
  736.                     *itemHit = iOKITEM;
  737.                     return true;
  738.                 }
  739.                 else    // otherwise convert the key into a tab and let it go
  740.                 {
  741.                     theEvent->message = 9;        // change it into a tab
  742.                     return false;
  743.                 }
  744.             }
  745.             
  746.             // if it was the escape key or cmd-. and the cancel button is enabled…
  747.             hControl = (ControlHandle)Dialog_GetItemHandle( theDialog, iCancelITEM );
  748.             if (iCancelITEM
  749.                 && (((theEvent->message & charCodeMask) == kEscape)
  750.                 || (((theEvent->message & charCodeMask) == '.') && (theEvent->modifiers & cmdKey)))
  751.                 && Dialog_ControlEnabled( hControl ))
  752.             {
  753.                 // hit the cancel button and get out.
  754.                 Dialog_BlinkControl( hControl );
  755.                 *itemHit = iCancelITEM;
  756.                 return true;
  757.             }
  758.             
  759.             // if the cmd key is down and there is an edit field, handle cut/copy/paste
  760.             if ((theEvent->modifiers & cmdKey) && ((DialogPeek) theDialog)->editField != -1)
  761.             {
  762.             long    theLength, scrapOffset;
  763.  
  764.                 // $$$$$ this stuff may not be necessary if we're running System 7.
  765.                 switch (cUpperCase( theEvent->message & charCodeMask ))
  766.                 {
  767.                     case 'X':
  768.                         if ((**((DialogPeek)theDialog)->textH).selEnd > (**((DialogPeek) theDialog)->textH).selStart)
  769.                         {
  770.                             ZeroScrap();    // in this case we must clear the current scrap
  771.                             TECut( ((DialogPeek)theDialog)->textH );
  772.                             TEToScrap();    // in this case we must force our cut into the scrap
  773.                         }
  774.                         return true;    // we handled it.
  775.                         
  776.                     case 'C':
  777.                         if ((**((DialogPeek)theDialog)->textH).selEnd > (**((DialogPeek)theDialog)->textH).selStart)
  778.                         {
  779.                             ZeroScrap();    // in this case we must clear the current scrap
  780.                             TECopy( ((DialogPeek)theDialog)->textH );
  781.                             TEToScrap();    // in this case we must force our cut into the scrap
  782.                         }
  783.                         return true;    // we handled it.
  784.                         
  785.                     case 'V':
  786.                         // Get the length of the TEXT on the clipboard
  787.                         theLength = GetScrap( nil, 'TEXT', &scrapOffset );
  788.                         
  789.                         // make sure the paste won't result in over 32K of text.
  790.                         if ((theLength > 0) && ((unsigned long)(**((DialogPeek)theDialog)->textH).teLength 
  791.                                 - ((**((DialogPeek)theDialog)->textH).selEnd - (**((DialogPeek)theDialog)->textH).selStart)
  792.                                 + theLength) > kMaxTextLength)
  793.                             SysBeep( 2 );
  794.                         else
  795.                             TEPaste( ((DialogPeek)theDialog)->textH );
  796.                         return true;    // we handled it.
  797.                     
  798.                     default:
  799.                         return false;    // we did not handle it.
  800.                 }
  801. //                *itemHit = 0;
  802.                 return false;    // we did not handle it.
  803.             }
  804.  
  805.             // if the cmd key is down or there's no edit field, handle keyboard equivs.
  806.             if ((theEvent->modifiers & cmdKey) || (((DialogPeek)theDialog)->editField == -1))
  807.             {
  808.                 /* handle command keys (or normal keys if no text edit field) for buttons */
  809.                 theCharCode = cUpperCase( theEvent->message & charCodeMask );
  810.                 iCount = iControlItem = 0;
  811.                 for (iItem=1; iItem <= **((short**)(((DialogPeek)theDialog)->items))+1; iItem++)
  812.                 {
  813.                     GetDialogItem( theDialog, iItem, &iKind, (Handle*)&hControl, &rRect );
  814.                     if ((iKind & 0x04) && !(iKind & 0x80))
  815.                     {
  816.                         /* control kind and not disabled */
  817.                         if ((rRect.left < 8192) && /* HideDItem adds 16384 to control to hide 'em */
  818.                                 ((**hControl).contrlVis == 255) && 
  819.                                 Dialog_ControlEnabled( hControl ))
  820.                         {
  821.                             GetControlTitle( hControl, s0 );
  822.                             if (s0[0] != '\0')
  823.                             {
  824.                                 if (theCharCode == cUpperCase( s0[1] ))
  825.                                 {
  826.                                     iCount++;
  827.                                     iControlItem = iItem;
  828.                                 }
  829.                             }
  830.                         }
  831.                     }
  832.                 }
  833.                 
  834.                 // if there is exactly one control that begins with the command letter,
  835.                 // then hit it.
  836.                 if (iCount == 1)
  837.                 {
  838.                     hControl = (ControlHandle)Dialog_GetItemHandle( theDialog, iControlItem );
  839.                     Dialog_BlinkControl( hControl );
  840.                     *itemHit = iControlItem;
  841.                     return true;        // we handled it.
  842.                 }
  843.                 
  844. //                theEvent->what = nullEvent;    /* don't accept other keystrokes when cmd key is down */
  845.             }
  846.             break;
  847.  
  848.         case updateEvt:
  849.             if (theEvent->message == (long)theDialog)    // if it's us…
  850.             {
  851.                 // and we need updating…
  852.                 if (!EmptyRgn( ((WindowPeek)theDialog)->updateRgn ))
  853.                 {
  854.                     GetPort( &savePort );
  855.                     SetPort( theDialog );
  856.  
  857.                     // iOKITEM
  858.                     if (((DialogPeek)theDialog)->aDefItem != 0)
  859.                         Dialog_OutlineButton( theDialog, ((DialogPeek)theDialog)->aDefItem );
  860.  
  861.                     BeginUpdate( theDialog );
  862.                     UpdateDialog( theDialog, theDialog->visRgn );
  863.                     EndUpdate( theDialog );
  864.                     SetPort( savePort );
  865.                 }
  866.                 return false;    // we handled it, but still return false!
  867.             }
  868.             break;
  869.     }
  870.     return false;    // we did not handle it.
  871. }
  872.  
  873. //----------------------------------------------------------------------------
  874. pascal Boolean bGenericDialogFilter(
  875.     DialogPtr        theDialog,
  876.     EventRecord        *theEvent,
  877.     short            *itemHit )
  878. {
  879.     return bDialogFilter( theDialog, theEvent, itemHit, 0L );
  880. }
  881.  
  882.